import { getCodeList } from '@/utils/codelist';
import { getGantPopupContainer, generateTree } from '@/utils/utils';
import { Selector } from 'gantd';
import { TreeSelect } from 'antd';
import type { WithBasicProps } from 'gantd/lib/compose/withbasic';
import React, { useEffect, useCallback, useMemo, useState, useRef } from 'react';
import { cloneDeep } from 'lodash';
import GridCellEditWrapper from '../gridcelleditwrapper';
import { isValueExist } from '@/utils/tool';

export type CodeListValue = any;
type BS = string | boolean;

const boolMap = new Map<BS, BS>([
  ['false', false],
  ['true', true],
  [false, 'false'],
  [true, 'true'],
]);

function formatBoolValue(value: BS | BS[]): CodeListValue {
  function formatBoolValueInner(value: BS): BS {
    if (boolMap.has(value)) {
      return boolMap.get(value) as BS;
    }
    return value;
  }

  if (Array.isArray(value)) {
    return value.map(formatBoolValueInner) as CodeListValue;
  }
  return formatBoolValueInner(value as BS);
}

export interface CodeListProps extends WithBasicProps {
  type: string;
  value: BS;
  cacheKey?: string;
  multiple?: boolean;
  mode?: string;
  onChange?: (v: CodeListValue) => void;
  filterFn?: (data: any) => any;
  allowEdit?: boolean;
  customGetCodeList?: (type: string) => Promise<any[]>; // 自定义获取数据源的实现
  selectAll?: boolean; // 新增：控制是否全选
}

type CodeListIf = {
  type: string;
  [key: string]: any;
};

const CodeList = React.forwardRef<HTMLDivElement, CodeListProps>((props: CodeListIf, ref) => {
  const {
    type,
    value,
    onChange,
    onSave,
    filterFn,
    cacheKey,
    placeholder = tr('请选择'),
    disableGroup = true,
    showGroup = true,
    customGetCodeList,
    defaultValue,
    selectAll = false, // 默认不全选
    ...restProps
  } = props;
  const [dataSource, setDataSource] = useState([]);
  const [codetype, setCodeType] = useState('list');
  const foucsRef = useRef(restProps.autoFocus);

  const selectBlur = useCallback(() => {
    setTimeout(() => {
      if (foucsRef.current) return;
      props?.onBlur?.();
    }, 20);
  }, [props.onBlur]);

  const query = useCallback(async () => {
    const list = typeof customGetCodeList === 'function' ? await customGetCodeList(type) : await getCodeList(type);

    const _list = filterFn ? filterFn(list) : list;
    const isHas = _list.findIndex((val: Object) => val?.isGroup);
    let newlist = cloneDeep(_list);
    if (isHas != -1) {
      //存在组
      _list.map((val) => {
        val.key = val.value;
        val.title = val.name;
        if (disableGroup) {
          val.disabled = val?.isGroup;
        }
        return val;
      });
      newlist = generateTree(_list, 'groupId');
      if (showGroup) {
        setCodeType('group');
      }
    }
    setDataSource(newlist);
  }, [customGetCodeList, type, filterFn]);

  const boolValue = useMemo(() => formatBoolValue(value), [value]);

  const onValueChange = useCallback((val: CodeListValue) => {
    if (onChange) onChange(formatBoolValue(val as BS));
    foucsRef.current = false;
  }, []);

  const save = useCallback((id, val, cb) => {
    if (onSave) onSave(id, formatBoolValue(val), cb);
  }, []);

  const selectorId = useMemo(() => {
    let str = `codelist-${type}`;
    if (cacheKey) str += `-${cacheKey}`;
    return str;
  }, [cacheKey, type]);

  useEffect(() => {
    type && query();
  }, [type]);

  // 监听 dataSource 变化，如果启用了全选则自动选择所有选项
  useEffect(() => {
    if (selectAll && dataSource.length > 0 && props.multiple && onChange) {
      // 从 dataSource 中提取所有可选值
      const allValues = dataSource.map((item) => item.value);
      // 调用 onChange 全选所有项
      onChange(formatBoolValue(allValues));
    }
  }, [dataSource, selectAll, props.multiple, onChange]);

  useEffect(() => {
    if (isValueExist(defaultValue)) {
      // NOTE:这里会执行多次 但是作为手动初始化没有什么毛病
      onChange(defaultValue);
    }
  }, [defaultValue, dataSource, onChange]);

  return (
    <div ref={ref}>
      {codetype == 'group' ? (
        <GridCellEditWrapper autoFocus onBlur={selectBlur}>
          <TreeSelect
            showSearch
            style={{ width: '100%' }}
            value={boolValue}
            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
            allowClear
            treeData={dataSource}
            treeDefaultExpandAll
            filterTreeNode={(val, treeNode) => {
              return treeNode.props?.name.includes(val);
            }}
            placeholder={placeholder}
            onChange={onValueChange}
            {...restProps}
            onBlur={() => {}}
            onFocus={() => {
              foucsRef.current = true;
            }}
          />
        </GridCellEditWrapper>
      ) : (
        <Selector
          getPopupContainer={getGantPopupContainer}
          useStorage={false}
          selectorId={selectorId}
          dataSource={dataSource}
          valueProp="value"
          labelProp="name"
          value={boolValue}
          onChange={onValueChange}
          onSave={save}
          placeholder={placeholder}
          {...restProps}
        />
      )}
    </div>
  );
});

CodeList.displayName = 'CodeList';

export default CodeList;
